﻿using System;
using System.Collections.Generic;
using Halo2BetaMap = Abide_Halo_Library.Halo_2_Beta_Map.Halo2BetaMap;
using Halo2Map = Abide_Halo_Library.Halo_2_Map.Halo2Map;
using IndexEntry_Halo2BetaMap = Abide_Halo_Library.Halo_2_Beta_Map.IndexEntry;
using IndexEntry_Halo2Map = Abide_Halo_Library.Halo_2_Map.IndexEntry;

namespace Abide.HaloMap
{
    public static class Halo2BetaMapExtensions
    {
        public static System.Windows.Forms.TreeNode[] GetTreeViewTagTypes(this Halo2BetaMap Map)
        {
            //Prepare
            List<System.Windows.Forms.TreeNode> Nodes = new List<System.Windows.Forms.TreeNode>();
            List<String> Classes = new List<String>();
            System.Windows.Forms.TreeNode TempNode = null;

            //Loop...
            for (Int32 i = 0; i < Map.IndexEntries.Length; i++)
            {
                //Get Entry...
                IndexEntry_Halo2BetaMap Entry = Map.IndexEntries[i];

                //Add Class Node...
                if (!Classes.Contains(Entry.Class))
                {
                    TempNode = new System.Windows.Forms.TreeNode();
                    TempNode.ImageIndex = 1;
                    TempNode.SelectedImageIndex = 1;
                    TempNode.Tag = null;

                    TempNode.Text = String.Format("[{0}] - {1}", Entry.Class.Replace(" ", String.Empty), Map.GetTypeDescription(Entry.Class));
                    Nodes.Add(TempNode);
                    Classes.Add(Entry.Class);
                }

                //Add to appropriate node...
                TempNode = new System.Windows.Forms.TreeNode(Entry.FileName);

                //Change Icon?
                Map.HandleClassIcon(ref TempNode, Entry.Class);

                //Final Preparations...
                TempNode.Tag = Entry.Ident;

                //Add...
                Nodes[Classes.IndexOf(Entry.Class)].Nodes.Add(TempNode);
            }

            //Return...
            return Nodes.ToArray();
        }
        public static System.Windows.Forms.TreeNode[] GetTreeViewFolder(this Halo2BetaMap Map)
        {
            //Create List...
            List<System.Windows.Forms.TreeNode> Nodes = new List<System.Windows.Forms.TreeNode>();
            System.Windows.Forms.TreeNode TempNode = null;

            //Loop through Each Tag...
            for (Int32 i = 0; i < Map.IndexEntries.Length; i++)
            {
                //Get Entry...
                IndexEntry_Halo2BetaMap Entry = Map.IndexEntries[i];

                //Get Path...
                string[] Path = Entry.FileName.Split('\\');

                if (Path.Length == 1)
                {
                    //Prepare
                    TempNode = new System.Windows.Forms.TreeNode(string.Format("{0}.{1}", Path[0], Entry.Class));
                    Map.HandleClassIcon(ref TempNode, Entry.Class);
                    TempNode.Tag = Entry.Ident;

                    //Add...
                    Nodes.Add(TempNode);
                }
                else
                {
                    Int32 Index = 0;
                    bool CreateNew = true;

                    for (Int32 x = 0; x < Nodes.Count; x++)
                    {
                        //Check...
                        if (Nodes[x].Text == Path[0])
                        {
                            Index = x;
                            CreateNew = false;
                            break;
                        }
                    }

                    if (CreateNew)
                    {
                        //Prepare...
                        TempNode = new System.Windows.Forms.TreeNode(Path[0]);
                        TempNode.ImageIndex = 1;
                        TempNode.SelectedImageIndex = 1;
                        TempNode.Tag = null;

                        //Loop...
                        Map.LoopTreeViewFolder(TempNode, Entry, 1);

                        //Add...
                        Nodes.Add(TempNode);
                    }
                    else
                    {
                        //Prepare
                        TempNode = Nodes[Index];

                        //Loop...
                        Map.LoopTreeViewFolder(TempNode, Entry, 1);

                        //Add...
                        Nodes[Index] = TempNode;
                    }
                }
            }

            //Return
            return Nodes.ToArray();
        }
        private static void LoopTreeViewFolder(this Halo2BetaMap Map, System.Windows.Forms.TreeNode Parent, IndexEntry_Halo2BetaMap Entry, Int32 StartingPoint)
        {
            //Prepare...
            System.Windows.Forms.TreeNode TempNode = null;
            string[] Path = Entry.FileName.Split('\\');
            bool CreateNew = true;
            Int32 Index = 0;


            //Done?
            if (Path.Length - 1 == StartingPoint)
            {
                //Prepare
                TempNode = new System.Windows.Forms.TreeNode(string.Format("{0}.{1}", Path[StartingPoint], Entry.Class));
                Map.HandleClassIcon(ref TempNode, Entry.Class);
                TempNode.Tag = Entry.Ident;

                //Finish...
                Parent.Nodes.Add(TempNode);
                return;
            }
            else
            {
                //Check...
                for (Int32 i = 0; i < Parent.Nodes.Count; i++)
                {
                    if (Parent.Nodes[i].Text == Path[StartingPoint])
                    {
                        CreateNew = false;
                        Index = i;
                        break;
                    }
                }

                //Add / Create...
                if (CreateNew)
                {
                    //Prepare...
                    TempNode = new System.Windows.Forms.TreeNode(Path[StartingPoint]);
                    TempNode.ImageIndex = 1;
                    TempNode.SelectedImageIndex = 1;
                    TempNode.Tag = null;

                    //Loop...
                    Map.LoopTreeViewFolder(TempNode, Entry, StartingPoint + 1);

                    //Add...
                    Parent.Nodes.Add(TempNode);
                }
                else
                {
                    //Prepare
                    TempNode = Parent.Nodes[Index];

                    //Loop...
                    Map.LoopTreeViewFolder(TempNode, Entry, StartingPoint + 1);

                    //Add
                    Parent.Nodes[Index] = TempNode;
                }
            }
        }
        private static void HandleClassIcon(this Halo2BetaMap Map, ref System.Windows.Forms.TreeNode Node, String Class)
        {
            //Check Class...
            switch (Class)
            {
                case "bitm":
                    Node.ImageIndex = 3;
                    Node.SelectedImageIndex = 3;
                    break;
                case "snd!":
                    Node.ImageIndex = 4;
                    Node.SelectedImageIndex = 4;
                    break;

                case "nhdt":
                    Node.ImageIndex = 6;
                    Node.SelectedImageIndex = 6;
                    break;

                case "sbsp":
                    Node.ImageIndex = 5;
                    Node.SelectedImageIndex = 5;
                    break;

                default:
                    Node.ImageIndex = 2;
                    Node.SelectedImageIndex = 2;
                    break;
            }
        }
        private static String GetTypeDescription(this Halo2BetaMap Map, String Type)
        {
            String Description = String.Empty;

            switch (Type.Trim())
            {
                case "matg":
                    Description = "Match Globals";
                    break;

                case "sncl":
                    Description = "Sound Classes";
                    break;

                case "spk!":
                    Description = "Sound Dialoge";
                    break;

                case "sky":
                    Description = "Sky";
                    break;

                case "scnr":
                    Description = "Scenario";
                    break;

                case "mode":
                    Description = "Model";
                    break;

                case "shad":
                    Description = "Shading Material";
                    break;

                case "stem":
                    Description = "Shader Templates";
                    break;

                case "spas":
                    Description = "Shader Passes";
                    break;

                case "bitm":
                    Description = "Bitmap";
                    break;

                case "vrtx":
                    Description = "Vertex Shaders";
                    break;

                case "lens":
                    Description = "Lense Flares";
                    break;

                case "scen":
                    Description = "Scenery Objects";
                    break;

                case "hlmt":
                    Description = "Object Properties";
                    break;

                case "jmad":
                    Description = "JMS Animation Graph";
                    break;

                case "effe":
                    Description = "Effect";
                    break;

                case "prt3":
                    Description = "Particle";
                    break;

                case "pmov":
                    Description = "Particle Physics";
                    break;

                case "lsnd":
                    Description = "Looping Sound";
                    break;

                case "snd!":
                    Description = "Sound";
                    break;

                case "coll":
                    Description = "Collision Geometry";
                    break;

                case "phmo":
                    Description = "Physics Model";
                    break;

                case "PRTM":
                    Description = "Particle Model";
                    break;

                case "ssce":
                    Description = "Sound Scenery";
                    break;

                case "ligh":
                    Description = "Light Object";
                    break;

                case "itmc":
                    Description = "Item Collections";
                    break;

                case "weap":
                    Description = "Weapon";
                    break;

                case "foot":
                    Description = "Material Effect";
                    break;

                case "deca":
                    Description = "Decal";
                    break;

                case "jpt!":
                    Description = "Damage Effect";
                    break;

                case "nhdt":
                    Description = "New HUD Interface";
                    break;

                case "eqip":
                    Description = "Equipment";
                    break;

                case "proj":
                    Description = "Projectile";
                    break;

                case "cont":
                    Description = "Contrail";
                    break;

                case "pphy":
                    Description = "Point Physics";
                    break;

                case "MGS2":
                    Description = "Light Volume";
                    break;

                case "vehc":
                    Description = "Vehicle Collection";
                    break;

                case "vehi":
                    Description = "Vehicle";
                    break;

                case "bloc":
                    Description = "Obstacle";
                    break;

                case "trak":
                    Description = "Camera";
                    break;

                case "ant!":
                    Description = "Antenna";
                    break;

                case "snde":
                    Description = "Environmental Sound";
                    break;

                case "DECR":
                    Description = "Decorator";
                    break;

                case "unic":
                    Description = "Unicode String List";
                    break;

                case "mulg":
                    Description = "Multiplayer Globals";
                    break;

                case "sfx+":
                    Description = "Sound Effects";
                    break;

                case "<fx>":
                    Description = "DSP Effects";
                    break;

                case "snmx":
                    Description = "Sound Mix";
                    break;

                case "adlg":
                    Description = "AI Dialoge";
                    break;

                case "colo":
                    Description = "Color";
                    break;

                case "hudg":
                    Description = "Display Globals";
                    break;

                case "wgtz":
                    Description = "Widget Collections";
                    break;

                case "wigl":
                    Description = "Widget Globals";
                    break;

                case "skin":
                    Description = "UI Skin";
                    break;

                case "wgit":
                    Description = "Widget";
                    break;

                case "bipd":
                    Description = "Biped";
                    break;

                case "garb":
                    Description = "Garbage";
                    break;

                case "udlg":
                    Description = "Unit Dialog";
                    break;

                case "bsdt":
                    Description = "Breakable Surface";
                    break;

                case "gldf":
                    Description = "Global Lighting";
                    break;

                case "clwd":
                    Description = "Blowing Cloth";
                    break;

                case "tdtl":
                    Description = "Beam Trail";
                    break;

                case "char":
                    Description = "Character";
                    break;

                case "styl":
                    Description = "Situational AI Style";
                    break;

                case "crea":
                    Description = "Creature";
                    break;

                case "weat":
                    Description = "Weather";
                    break;

                case "mach":
                    Description = "Machine";
                    break;

                case "mdlg":
                    Description = "Level Specific Dialog";
                    break;

                case "egor":
                    Description = "Screen FX";
                    break;

                case "ctrl":
                    Description = "Control";
                    break;

                case "phys":
                    Description = "Physics";
                    break;

                case "fog":
                    Description = "Cluster Fog";
                    break;

                case "fpch":
                    Description = "Fog Patch";
                    break;

                case "goof":
                    Description = "Goofy";
                    break;

                case "sily":
                    Description = "Silly Goose";
                    break;

                case "ltmp":
                    Description = "Lightmap";
                    break;

                case "sbsp":
                    Description = "Structure Binary Separation Plane";
                    break;

                case "ugh!":
                    Description = "Sound Diagnostic";
                    break;

                default:
                    Description = "<No Description Set>";
                    break;
            }

            return Description;
        }
    }

    public static class Halo2MapExtensions
    {
        public static System.Windows.Forms.TreeNode[] GetTreeViewTagTypes(this Halo2Map Map)
        {
            //Prepare
            List<System.Windows.Forms.TreeNode> Nodes = new List<System.Windows.Forms.TreeNode>();
            List<String> Classes = new List<String>();
            System.Windows.Forms.TreeNode TempNode = null;

            //Loop...
            for (int i = 0; i < Map.IndexEntries.Length; i++)
            {
                //Get Entry...
                IndexEntry_Halo2Map Entry = Map.IndexEntries[i];

                //Add Class Node...
                if (!Classes.Contains(Entry.Class))
                {
                    TempNode = new System.Windows.Forms.TreeNode();
                    TempNode.ImageIndex = 1;
                    TempNode.SelectedImageIndex = 1;
                    TempNode.Tag = null;

                    TempNode.Text = String.Format("[{0}] - {1}", Entry.Class.Replace(" ", String.Empty), Map.GetTypeDescription(Entry.Class));
                    Nodes.Add(TempNode);
                    Classes.Add(Entry.Class);
                }

                //Add to appropriate node...
                TempNode = new System.Windows.Forms.TreeNode(Entry.FileName);

                //Change Icon?
                Map.HandleClassIcon(ref TempNode, Entry.Class);

                //Final Preparations...
                TempNode.Tag = Entry.Ident;

                //Add...
                Nodes[Classes.IndexOf(Entry.Class)].Nodes.Add(TempNode);
            }

            //Return...
            return Nodes.ToArray();
        }
        public static System.Windows.Forms.TreeNode[] GetTreeViewFolder(this Halo2Map Map)
        {
            //Create List...
            List<System.Windows.Forms.TreeNode> Nodes = new List<System.Windows.Forms.TreeNode>();
            System.Windows.Forms.TreeNode TempNode = null;

            //Loop through Each Tag...
            for (int i = 0; i < Map.IndexEntries.Length; i++)
            {
                //Get Entry...
                IndexEntry_Halo2Map Entry = Map.IndexEntries[i];

                //Get Path...
                String[] Path = Entry.FileName.Split('\\');

                if (Path.Length == 1)
                {
                    //Prepare
                    TempNode = new System.Windows.Forms.TreeNode(String.Format("{0}.{1}", Path[0], Entry.Class));
                    Map.HandleClassIcon(ref TempNode, Entry.Class);
                    TempNode.Tag = Entry.Ident;

                    //Add...
                    Nodes.Add(TempNode);
                }
                else
                {
                    Int32 Index = 0;
                    bool CreateNew = true;

                    for (int x = 0; x < Nodes.Count; x++)
                    {
                        //Check...
                        if (Nodes[x].Text == Path[0])
                        {
                            Index = x;
                            CreateNew = false;
                            break;
                        }
                    }

                    if (CreateNew)
                    {
                        //Prepare...
                        TempNode = new System.Windows.Forms.TreeNode(Path[0]);
                        TempNode.ImageIndex = 1;
                        TempNode.SelectedImageIndex = 1;
                        TempNode.Tag = null;

                        //Loop...
                        Map.LoopTreeViewFolder(TempNode, Entry, 1);

                        //Add...
                        Nodes.Add(TempNode);
                    }
                    else
                    {
                        //Prepare
                        TempNode = Nodes[Index];

                        //Loop...
                        Map.LoopTreeViewFolder(TempNode, Entry, 1);

                        //Add...
                        Nodes[Index] = TempNode;
                    }
                }
            }

            //Return
            return Nodes.ToArray();
        }
        private static void LoopTreeViewFolder(this Halo2Map Map, System.Windows.Forms.TreeNode Parent, IndexEntry_Halo2Map Entry, Int32 StartingPoint)
        {
            //Prepare...
            System.Windows.Forms.TreeNode TempNode = null;
            String[] Path = Entry.FileName.Split('\\');
            bool CreateNew = true;
            Int32 Index = 0;


            //Done?
            if (Path.Length - 1 == StartingPoint)
            {
                //Prepare
                TempNode = new System.Windows.Forms.TreeNode(String.Format("{0}.{1}", Path[StartingPoint], Entry.Class));
                Map.HandleClassIcon(ref TempNode, Entry.Class);
                TempNode.Tag = Entry.Ident;

                //Finish...
                Parent.Nodes.Add(TempNode);
                return;
            }
            else
            {
                //Check...
                for (int i = 0; i < Parent.Nodes.Count; i++)
                {
                    if (Parent.Nodes[i].Text == Path[StartingPoint])
                    {
                        CreateNew = false;
                        Index = i;
                        break;
                    }
                }

                //Add / Create...
                if (CreateNew)
                {
                    //Prepare...
                    TempNode = new System.Windows.Forms.TreeNode(Path[StartingPoint]);
                    TempNode.ImageIndex = 1;
                    TempNode.SelectedImageIndex = 1;
                    TempNode.Tag = null;

                    //Loop...
                    Map.LoopTreeViewFolder(TempNode, Entry, StartingPoint + 1);

                    //Add...
                    Parent.Nodes.Add(TempNode);
                }
                else
                {
                    //Prepare
                    TempNode = Parent.Nodes[Index];

                    //Loop...
                    Map.LoopTreeViewFolder(TempNode, Entry, StartingPoint + 1);

                    //Add
                    Parent.Nodes[Index] = TempNode;
                }
            }
        }
        private static void HandleClassIcon(this Halo2Map Map, ref System.Windows.Forms.TreeNode Node, String Class)
        {
            //Check Class...
            switch (Class)
            {
                case "bitm":
                    Node.ImageIndex = 3;
                    Node.SelectedImageIndex = 3;
                    break;

                case "nhdt":
                    Node.ImageIndex = 6;
                    Node.SelectedImageIndex = 6;
                    break;

                case "snd!":
                    Node.ImageIndex = 4;
                    Node.SelectedImageIndex = 4;
                    break;

                case "sbsp":
                    Node.ImageIndex = 5;
                    Node.SelectedImageIndex = 5;
                    break;

                default:
                    Node.ImageIndex = 2;
                    Node.SelectedImageIndex = 2;
                    break;
            }
        }
        private static String GetTypeDescription(this Halo2Map Map, String Type)
        {
            String Description = String.Empty;

            switch (Type.Trim())
            {
                case "matg":
                    Description = "Match Globals";
                    break;

                case "sncl":
                    Description = "Sound Classes";
                    break;

                case "spk!":
                    Description = "Sound Dialoge";
                    break;

                case "sky":
                    Description = "Sky";
                    break;

                case "scnr":
                    Description = "Scenario";
                    break;

                case "mode":
                    Description = "Model";
                    break;

                case "shad":
                    Description = "Shading Material";
                    break;

                case "stem":
                    Description = "Shader Templates";
                    break;

                case "spas":
                    Description = "Shader Passes";
                    break;

                case "bitm":
                    Description = "Bitmap";
                    break;

                case "vrtx":
                    Description = "Vertex Shaders";
                    break;

                case "lens":
                    Description = "Lense Flares";
                    break;

                case "scen":
                    Description = "Scenery Objects";
                    break;

                case "hlmt":
                    Description = "Object Properties";
                    break;

                case "jmad":
                    Description = "JMS Animation Graph";
                    break;

                case "effe":
                    Description = "Effect";
                    break;

                case "prt3":
                    Description = "Particle";
                    break;

                case "pmov":
                    Description = "Particle Physics";
                    break;

                case "lsnd":
                    Description = "Looping Sound";
                    break;

                case "snd!":
                    Description = "Sound";
                    break;

                case "coll":
                    Description = "Collision Geometry";
                    break;

                case "phmo":
                    Description = "Physics Model";
                    break;

                case "PRTM":
                    Description = "Particle Model";
                    break;

                case "ssce":
                    Description = "Sound Scenery";
                    break;

                case "ligh":
                    Description = "Light Object";
                    break;

                case "itmc":
                    Description = "Item Collections";
                    break;

                case "weap":
                    Description = "Weapon";
                    break;

                case "foot":
                    Description = "Material Effect";
                    break;

                case "deca":
                    Description = "Decal";
                    break;

                case "jpt!":
                    Description = "Damage Effect";
                    break;

                case "nhdt":
                    Description = "New HUD Interface";
                    break;

                case "eqip":
                    Description = "Equipment";
                    break;

                case "proj":
                    Description = "Projectile";
                    break;

                case "cont":
                    Description = "Contrail";
                    break;

                case "pphy":
                    Description = "Point Physics";
                    break;

                case "MGS2":
                    Description = "Light Volume";
                    break;

                case "vehc":
                    Description = "Vehicle Collection";
                    break;

                case "vehi":
                    Description = "Vehicle";
                    break;

                case "bloc":
                    Description = "Obstacle";
                    break;

                case "trak":
                    Description = "Camera";
                    break;

                case "ant!":
                    Description = "Antenna";
                    break;

                case "snde":
                    Description = "Environmental Sound";
                    break;

                case "DECR":
                    Description = "Decorator";
                    break;

                case "unic":
                    Description = "Unicode String List";
                    break;

                case "mulg":
                    Description = "Multiplayer Globals";
                    break;

                case "sfx+":
                    Description = "Sound Effects";
                    break;

                case "<fx>":
                    Description = "DSP Effects";
                    break;

                case "snmx":
                    Description = "Sound Mix";
                    break;

                case "adlg":
                    Description = "AI Dialoge";
                    break;

                case "colo":
                    Description = "Color";
                    break;

                case "hudg":
                    Description = "Display Globals";
                    break;

                case "wgtz":
                    Description = "Widget Collections";
                    break;

                case "wigl":
                    Description = "Widget Globals";
                    break;

                case "skin":
                    Description = "UI Skin";
                    break;

                case "wgit":
                    Description = "Widget";
                    break;

                case "bipd":
                    Description = "Biped";
                    break;

                case "garb":
                    Description = "Garbage";
                    break;

                case "udlg":
                    Description = "Unit Dialog";
                    break;

                case "bsdt":
                    Description = "Breakable Surface";
                    break;

                case "gldf":
                    Description = "Global Lighting";
                    break;

                case "clwd":
                    Description = "Blowing Cloth";
                    break;

                case "tdtl":
                    Description = "Beam Trail";
                    break;

                case "char":
                    Description = "Character";
                    break;

                case "styl":
                    Description = "Situational AI Style";
                    break;

                case "crea":
                    Description = "Creature";
                    break;

                case "weat":
                    Description = "Weather";
                    break;

                case "mach":
                    Description = "Machine";
                    break;

                case "mdlg":
                    Description = "Level Specific Dialog";
                    break;

                case "egor":
                    Description = "Screen FX";
                    break;

                case "ctrl":
                    Description = "Control";
                    break;

                case "phys":
                    Description = "Physics";
                    break;

                case "fog":
                    Description = "Cluster Fog";
                    break;

                case "fpch":
                    Description = "Fog Patch";
                    break;

                case "goof":
                    Description = "Goofy";
                    break;

                case "sily":
                    Description = "Silly Goose";
                    break;

                case "ltmp":
                    Description = "Lightmap";
                    break;

                case "sbsp":
                    Description = "Structure Binary Separation Plane";
                    break;

                case "ugh!":
                    Description = "Sound Diagnostic";
                    break;

                default:
                    Description = "<No Description Set>";
                    break;
            }

            return Description;
        }
    }
}
